<script setup lang="ts">
import { reactive, ref } from "vue";
import { onLoad, onUnload } from "@dcloudio/uni-app";
import { useQuery } from "@/hooks/init";
import { useShare } from "@/hooks/share";
import { useTabs } from "@/hooks/page";
import { mini_course_detail_api } from "@/package/study/api/course";
import { share_check_api } from "@/package/study/api/course_order";
import { data_api } from "@/api/my";
import { add_cancel_favorite_api } from "@/api/favorite";
import { EV_ORDER } from "@/constant/event";
import { AppData } from "@/utils/app";
import { Account } from "@/utils/account";
import { numToMinute } from "@/utils/number";
import { Router } from "@/utils/router";
import { Toast } from "@/utils/toast";

import NavBack from "@/components/nav/back.vue";
import PageSticky from "@/components/page/sticky.vue";
import DetailTabItem from "./components/detail-tab-item.vue";
import DetailChapterItem from "./components/detail-chapter-item.vue";
import DetailMenuItem from "./components/detail-menu-item.vue";
import ServiceContact from "@/components/service/contact.vue";
import PopupBottom from "@/components/popup/bottom.vue";
import PopupModal from "@/components/popup/modal.vue";

onLoad((options) => {
  useQuery<{
    id: string;
    batch_no?: string;
    share_uid?: string;
    guiderId?: string;
  }>(options as MiniApp.AppLaunchOption, (query) => {
    tempData.id = query.id;
    groupData.batchNo = query.batch_no || "";
    tempData.share_uid = query.share_uid || "";
    reloadData().then((resp) => {
      const mini_detail = resp.mini_detail;
      infoData.img = mini_detail.cover_img;
      infoData.name = mini_detail.title;
      infoData.desc = mini_detail.short_brief;
      infoData.tag = mini_detail.tag;
      infoData.update = mini_detail.update_status;
      infoData.intro = mini_detail.brief.replace(
        /\<img/gi,
        '<img class="detail-intro-img" '
      );
      groupData.type = mini_detail.price_type;
      groupData.price1 = mini_detail.single_goods_info?.price;
      groupData.price2 = mini_detail.groupon_goods_info?.price;
      groupData.num1 = mini_detail.need_member_num;

      tempData.welfare_group_id = mini_detail.welfare_group_id;

      shareOption.imageUrl = mini_detail.cover_img;
      shareOption.title = mini_detail.title;
    });

    Account.isLogin && reloadMyData();

    shareOption.data = { id: query.id };
    shareOption.data.batch_no = query.batch_no || "";

    tempData.guiderId = query.guiderId || "";

    uni.$on(EV_ORDER, evOrderCallback);
  });
});
onUnload(() => uni.$off(EV_ORDER, evOrderCallback));

const reloadMyData = () => {
  return data_api<{ course_favorite?: { fav_id: number }[] }>({
    includes: "course_favorite",
  }).then((resp) => {
    const id = Number(tempData.id);
    myData.isCollect = !!resp.course_favorite?.some((i) => i.fav_id === id);
  });
};

const reloadData = () => {
  isLogin.value = Account.isLogin;
  return mini_course_detail_api({
    id: tempData.id,
    batch_no: groupData.batchNo,
  }).then((resp) => {
    const mini_detail = resp.mini_detail;
    myData.isPay = mini_detail.has_pay === 1;
    myData.isGroup = mini_detail.has_groupon === 1;
    groupData.num2 = mini_detail.member_left;
    // 已登录，不是自己分享，则显示助力；未登录，有 share_uid 则显示助力
    isShare.value = tempData.share_uid
      ? isLogin.value
        ? tempData.share_uid !== `${AppData.userData.uid}`
        : true
      : false;

    // 刷新节目
    const _albumList = [
      ...(resp.mini_trial_list && resp.mini_trial_list.length !== 0
        ? [{ id: tempData.id, title: "试听", chapter: resp.mini_trial_list }]
        : []),
      ...resp.mini_course_list,
    ];
    albumList.value = _albumList.map((i) => {
      return {
        id: i.id,
        title: i.title,
        chapter: i.chapter.map((j: any) => {
          return {
            id: j.id,
            title: j.title,
            img: j.imgs[0]?.img_url || "",
            url: j.media_url,
            duration: j.duration,
            intro: j.brief,
            canListen: j.is_trial === 1, // 试听
            type: j.media_type,
          };
        }),
      };
    });

    shareOption.data.batch_no = mini_detail.order_info?.batch_no || "";
    return resp;
  });
};

const isLogin = ref(false);
const isShare = ref(false);

const infoData = reactive({
  img: "",
  name: "",
  desc: "",
  tag: [] as string[],
  update: "",
  intro: "",
});

let videoCtx: UniApp.VideoContext | undefined = undefined;
const videoData = reactive({
  poster: "",
  src: "",
  id: "",
  isPaused: true,
  currentTime: "",
});
const videoTimeUpdate = (e: MiniApp.Event<{ currentTime: number }>) => {
  videoData.currentTime = numToMinute(Math.floor(e.detail.currentTime));
};
const videoClick = () => {
  if (!videoCtx) {
    videoCtx = uni.createVideoContext("video");
  }
  videoData.isPaused ? videoCtx.play() : videoCtx.pause();
};

const tabList = ["目录", "介绍"];
const { tabData, tabClick, tabChange } = useTabs();

const albumList = ref<{ id: string; title: string; chapter: any[] }[]>([]);
const programClick = (index: number, index2: number, type: 1) => {
  const program = albumList.value[index].chapter[index2];
  if (type === 1) {
    // 详情
    chapterData.title = program.title;
    chapterData.intro = program.intro;
    chapterVisible.value = true;
  } else {
    if (!(program.canListen || myData.isGroup)) return Toast.show("非试听节目");
    videoData.poster = program.img;
    videoData.src = program.url;
    videoData.id = program.id;
    videoData.isPaused = false;
    videoData.currentTime = "00:00";
  }
};

const chapterVisible = ref(false);
const chapterData = reactive({ title: "", intro: "" });

// type：0：免费；1：只能单买；2：只能团购；3：单买 + 团购
// price1：单买；price2：团购；num1：成团需要人数；num2：还差人数
const groupData = reactive({
  type: 0,
  price1: "",
  price2: "",
  num1: 0,
  num2: 0,
  batchNo: "",
});

// 检查是否登录，未登录时，登录且刷新数据
const checkLoginAndReload = (callback: (isLogin: boolean) => void) => {
  Account.isLogin
    ? callback(false)
    : Account.checkLogin((isLogin) => {
        Toast.showLoading();
        reloadData()
          .then(() => callback(isLogin))
          .catch(() => Toast.hideLoading());
      });
};
const shareClick = () => {
  checkLoginAndReload(() => Toast.hideLoading());
};
const assistanceClick = () => {
  checkLoginAndReload(() => {
    myData.isGroup || !isShare.value
      ? Toast.hideLoading() // 点击助力按钮，登录后已成团或自己分享，则不处理
      : share_check_api({
          share_uid: tempData.share_uid,
          product_no: tempData.id,
        })
          .then(() => {
            isShare.value = false;
            Toast.hideLoading();
          })
          .catch(() => Toast.hideLoading());
  });
};
const buyClick = (type: 1 | 2) => {
  checkLoginAndReload((isLogin) => {
    Toast.hideLoading();
    if (myData.isPay || myData.isGroup) {
      isLogin && Router.navigateBack();
    } else {
      if (AppData.systemType === "ios")
        return popupModal.value?.show({
          content: "由于相关规范\niOS功能暂不可用",
          showCancel: false,
        });

      Router.navigateToOrRedirectTo(
        isLogin,
        `/package/study/pages/course/settle?${Router.dataToQuery({
          img: shareOption.imageUrl,
          name: infoData.name,
          price: type === 1 ? groupData.price1 : groupData.price2,
          priceType: type,
          productNo: tempData.id,
          batchNo: groupData.batchNo,
          guiderId: tempData.guiderId,
        })}`
      );
    }
  });
};

const groupClick = () => {
  Router.navigateTo(
    `/package/community/pages/group/detail?id=${tempData.welfare_group_id}`
  );
};

const myData = reactive({ isCollect: false, isPay: false, isGroup: false });
const collectClick = () => {
  const fn = () => {
    myData.isCollect = !myData.isCollect;
    add_cancel_favorite_api({
      favId: tempData.id,
      type: 17,
      status: myData.isCollect ? 1 : 2,
    });
  };

  Account.isLogin
    ? fn()
    : Account.login(() => {
        reloadMyData().then(() => {
          // 没有收藏，则收藏
          myData.isCollect || fn();
        });
      });
};

const evOrderCallback = (e: { type: "pay"; data: { type: "course" } }) => {
  console.info(`触发事件：${EV_ORDER}`, e);
  e.type === "pay" && e.data.type === "course" && reloadData();
};

const popupModal = ref<InstanceType<typeof PopupModal>>();
const tempData = { id: "", share_uid: "", welfare_group_id: "", guiderId: "" };

const { onShareAppMessage, onShareTimeline, shareOption } = useShare(
  "/package/study/pages/course/detail"
);
</script>

<template>
  <NavBack navigationBarTextStyle="white" />

  <PageSticky>
    <view class="detail-media">
      <video
        class="detail-media-video"
        v-if="videoData.src"
        id="video"
        :src="videoData.src"
        :poster="videoData.poster"
        autoplay
        show-fullscreen-btn
        controls
        show-center-play-btn
        show-play-btn
        show-progress
        objectFit="contain"
        play-btn-position="center"
        @timeupdate="videoTimeUpdate"
        @play="videoData.isPaused = false"
        @pause="videoData.isPaused = true"
        @ended="videoData.isPaused = true"
      />
      <view @click="videoClick">
        <image
          class="detail-media-img"
          v-if="!videoData.src.includes('.mp4')"
          :src="infoData.img"
          mode="aspectFill"
        />
        <template v-if="videoData.src.includes('.mp3')">
          <image
            class="detail-media-play"
            v-if="videoData.isPaused"
            src="@/package/study/static/course-play.png"
          />
          <view class="detail-media-time" v-else>
            {{ videoData.currentTime }}
          </view>
        </template>
      </view>
    </view>
  </PageSticky>

  <view class="detail-info">
    <view class="detail-info-name">{{ infoData.name }}</view>
    <view class="detail-info-desc">{{ infoData.desc }}</view>
    <view style="display: flex; align-items: center">
      <view class="detail-info-tag" v-for="i of infoData.tag" :key="i">
        {{ i }}
      </view>
      <view class="detail-info-update">{{ infoData.update }}</view>
    </view>
  </view>

  <view class="detail-tab">
    <view
      class="detail-tab-item"
      v-for="(i, d) of tabList"
      :key="d"
      @click="tabClick(d)"
    >
      <view style="position: relative">
        <DetailTabItem :isActive="tabData.index === d" :text="i" />
        <view class="detail-tab-tag" v-if="!myData.isGroup && d === 0">
          试听
        </view>
      </view>
    </view>
  </view>

  <swiper class="detail-swipe" :current="tabData.current" @change="tabChange">
    <swiper-item>
      <scroll-view class="detail-album" scroll-y>
        <view class="detail-albumw-rapper">
          <view v-for="(i, d) of albumList" :key="i.id">
            <view class="detail-album-title">{{ i.title }}</view>
            <view class="detail-album-chapter">
              <view
                v-for="(j, x) of i.chapter"
                :key="j.id"
                style="position: relative"
                @click="programClick(d, x)"
              >
                <view class="detail-album-line" v-if="x !== 0"></view>
                <DetailChapterItem
                  :info="j"
                  :isLock="!myData.isGroup"
                  :color="videoData.id === j.id ? '#ff7900' : ''"
                >
                  <image
                    class="detail-album-btn"
                    src="@/package/study/static/course-chapter.png"
                    v-if="myData.isGroup || j.canListen"
                    @click.stop="programClick(d, x, 1)"
                  />
                </DetailChapterItem>
              </view>
            </view>
          </view>
        </view>
      </scroll-view>
    </swiper-item>

    <swiper-item>
      <scroll-view class="detail-intro" scroll-y>
        <view class="detail-intro-wrapper">
          <!-- <navigator
            class="detail-intro-guide"
            v-if="guideData.id"
            :url="`/package/guide/pages/detail/course?id=${guideData.id}`"
          >
            <GuideInfo :info="guideData" />
          </navigator> -->
          <view class="detail-intro-html">
            <rich-text :nodes="infoData.intro" />
          </view>
        </view>
      </scroll-view>
    </swiper-item>
  </swiper>

  <view class="detail-fixed">
    <view class="detail-menu" @click="collectClick">
      <DetailMenuItem
        :icon="
          myData.isCollect
            ? '/package/study/static/course-collect2.png'
            : '/package/study/static/course-collect.png'
        "
        text="收藏"
      />
    </view>
    <view class="detail-menu" @click="contactClick">
      <DetailMenuItem
        icon="/package/study/static/course-contact.png"
        text="咨询"
      />
      <ServiceContact />
    </view>
    <view class="detail-menu" @click="groupClick">
      <DetailMenuItem
        icon="/package/study/static/course-group.png"
        text="社群"
      />
    </view>

    <view class="detail-btn" v-if="myData.isGroup" style="opacity: 0.5">
      课程已解锁
    </view>
    <view class="detail-btn" v-else-if="myData.isPay">
      还差{{ groupData.num2 }}人成团，分享给好友快速开课
      <button class="detail-btn-auth" open-type="share" />
    </view>
    <view class="detail-btn" v-else-if="groupData.type === 0">
      {{ isShare ? "助力解锁" : "去分享，好友助力后解锁课程" }}
      <view class="detail-btn-auth" @click="shareClick"></view>
      <view
        class="detail-btn-auth"
        v-if="isShare"
        @click="assistanceClick"
      ></view>
      <button class="detail-btn-auth" v-else-if="isLogin" open-type="share" />
    </view>
    <view class="detail-btn2" v-else-if="groupData.type === 3">
      <view class="detail-btn2-single" @click="buyClick(1)">
        <view class="detail-btn2-price">
          <view class="detail-btn2-price2">￥</view>{{ groupData.price1 }}
        </view>
        <view class="detail-btn2-text">单独购买</view>
      </view>
      <view class="detail-btn2-group" @click="buyClick(2)">
        <view class="detail-btn2-price">
          <view class="detail-btn2-price2">￥</view>{{ groupData.price2 }}
        </view>
        <view class="detail-btn2-text">
          {{
            groupData.batchNo
              ? `还差${groupData.num2}人成团，加入拼团`
              : `${groupData.num1}人成团`
          }}
        </view>
      </view>
    </view>
    <view class="detail-btn3" v-else @click="buyClick(groupData.type)">
      <view class="detail-btn3-price">
        <view class="detail-btn3-price2">￥</view>
        {{ groupData.type === 1 ? groupData.price1 : groupData.price2 }}
      </view>
      <view class="detail-btn3-text">
        {{ groupData.type === 1 ? "立即购买" : "拼团购买" }}
      </view>
    </view>
  </view>

  <PopupBottom
    v-model="chapterVisible"
    :title="chapterData.title"
    :safeAreaInsetBottom="false"
  >
    <view class="detail-chapter">
      <scroll-view class="detail-chapter-wrapper" scroll-y>
        <view class="detail-chapter-content">
          <rich-text :nodes="chapterData.intro" />
        </view>
      </scroll-view>
    </view>
  </PopupBottom>

  <PopupModal ref="popupModal" />
</template>

<style lang="scss">
page {
  padding-bottom: 0;
}

.detail-media {
  position: relative;
  height: 420rpx;

  .detail-media-video {
    display: block;
    width: 100%;
    height: 100%;
    background-color: #000000;
  }

  .detail-media-img {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }

  .detail-media-play,
  .detail-media-time {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

  .detail-media-play {
    width: 84rpx;
    height: 84rpx;
  }

  .detail-media-time {
    width: 132rpx;
    font-size: 28rpx;
    color: #ffffff;
    line-height: 56rpx;
    text-align: center;
    border-radius: 4rpx;
    background-color: rgba(0, 0, 0, 0.5);
  }
}

.detail-info {
  padding: 30rpx;
  background-color: #ffffff;

  .detail-info-name {
    margin-bottom: 16rpx;
    font-size: 32rpx;
    color: #333333;
    line-height: 44rpx;
    font-weight: bold;
  }

  .detail-info-desc {
    margin-bottom: 32rpx;
    font-size: 24rpx;
    color: #bcbcbc;
    line-height: 32rpx;
  }

  .detail-info-tag {
    padding: 0 6rpx;
    margin-right: 10rpx;
    font-size: 20rpx;
    color: #1da7ff;
    line-height: 36rpx;
    border-radius: 4rpx;
    background-color: rrgba(29, 212, 255, 0.05);
  }

  .detail-info-update {
    margin-left: auto;
    font-size: 26rpx;
    color: #999999;
    line-height: 32rpx;
  }
}

.detail-tab {
  display: flex;
  align-items: center;
  height: 88rpx;
  background-color: #ffffff;

  .detail-tab-item {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 25%;
  }

  .detail-tab-tag {
    position: absolute;
    left: 100%;
    top: -8rpx;
    padding: 0 8rpx;
    font-size: 22rpx;
    color: #ffffff;
    line-height: 28rpx;
    white-space: nowrap;
    background-color: #27c9a8;
    border-radius: 44rpx 44rpx 44rpx 2rpx;
  }
}

.detail-swipe {
  height: calc(100vh - 506rpx);
}

.detail-album {
  height: 100%;

  .detail-albumw-rapper {
    padding-top: 30rpx;
    padding-bottom: calc(130rpx + env(safe-area-inset-bottom));
  }

  .detail-album-title {
    padding-left: 30rpx;
    margin-bottom: 30rpx;
    font-size: 28rpx;
    color: #333333;
    line-height: 48rpx;
    font-weight: bold;
  }

  .detail-album-chapter {
    margin: 0 30rpx 30rpx;
    border-radius: 6rpx;
    background-color: #ffffff;
  }

  .detail-album-line {
    position: absolute;
    left: 30rpx;
    top: 0;
    right: 30rpx;
    border-bottom: 2rpx solid #eeeeee;
  }

  .detail-album-btn {
    flex-shrink: 0;
    width: 40rpx;
    height: 40rpx;
    margin-left: 30rpx;
  }
}

.detail-intro {
  height: 100%;

  .detail-intro-wrapper {
    padding: 30rpx 30rpx env(safe-area-inset-bottom);
  }

  .detail-intro-html {
    padding-bottom: 150rpx;
  }

  .detail-intro-img {
    width: 100%;
  }
}

.detail-fixed {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  height: 120rpx;
  padding-left: 14rpx;
  padding-right: 30rpx;
  padding-bottom: env(safe-area-inset-bottom);
  background-color: #ffffff;
}

.detail-menu {
  position: relative;
  flex-shrink: 0;
  width: 76rpx;
}

.detail-btn {
  position: relative;
  flex-grow: 1;
  min-width: 0;
  margin-left: 16rpx;
  font-size: 28rpx;
  color: #ffffff;
  line-height: 90rpx;
  text-align: center;
  border-radius: 46rpx;
  background-color: #ff7900;

  .detail-btn-auth {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    opacity: 0;
  }
}

.detail-btn2 {
  position: relative;
  flex-grow: 1;
  min-width: 0;
  height: 90rpx;
  margin-left: 16rpx;

  .detail-btn2-single,
  .detail-btn2-group {
    position: absolute;
    top: 0;
    width: 58%;
    height: 100%;
    padding-top: 8rpx;
    border-radius: 46rpx;
    background-color: #ff7900;
    box-sizing: border-box;
  }

  .detail-btn2-single {
    left: 0;
    padding-right: 6%;
    opacity: 0.23;
  }

  .detail-btn2-group {
    right: 0;
    width: 54%;
  }

  .detail-btn2-price {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    font-size: 36rpx;
    color: #ffffff;
    line-height: 40rpx;
    font-weight: bold;
  }

  .detail-btn2-price2 {
    font-size: 24rpx;
    line-height: 36rpx;
  }

  .detail-btn2-text {
    font-size: 26rpx;
    color: #ffffff;
    line-height: 34rpx;
    text-align: center;
  }
}

.detail-btn3 {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-grow: 1;
  min-width: 0;
  height: 90rpx;
  margin-left: 16rpx;
  border-radius: 46rpx;
  background-color: #ff7900;

  .detail-btn3-price {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    font-size: 40rpx;
    color: #ffffff;
    line-height: 56rpx;
    font-weight: bold;
  }

  .detail-btn3-price2 {
    font-size: 28rpx;
    line-height: 48rpx;
  }

  .detail-btn3-text {
    margin-left: 20rpx;
    font-size: 28rpx;
    color: #ffffff;
  }
}

.detail-chapter {
  .detail-chapter-wrapper {
    height: 70vh;
  }

  .detail-chapter-content {
    padding: 10rpx 30rpx calc(30rpx + env(safe-area-inset-bottom));
  }
}
</style>